﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using ModelBinder.Extension.AspNetCore.FromSmartBody;
using VueShopApi.Common;
using VueShopApi.Common.Extensions;
using VueShopApi.Dtos;
using VueShopApi.Entities;

namespace VueShopApi.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class CategoriesController : AuthorizeController
    {
        private readonly ILogger<CategoriesController> _logger;
        private readonly IFreeSql _context;

        public CategoriesController(ILogger<CategoriesController> logger, IFreeSql context)
        {
            _logger = logger;
            _context = context;
        }

        /// <summary>
        /// 获取所有分类
        /// </summary>
        /// <param name="type"></param>
        /// <param name="pagenum"></param>
        /// <param name="pagesize"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetAllCategories(int type = 3, int pagenum = 1, int pagesize = 5)
        {
            var categories = await _context.Select<SpCategory>().Where(c => c.CatDeleted == 0)
                //.Count(out var total)
                //.Page(pagenum, pagesize)
                .ToListAsync<CategoryDto>();

            var result = GetCategoriesTree(categories, type);
            // pagenum -= 1;
            return ServerResponse.Yes(new
            {
                total = result.Count,
                pagenum,
                pagesize,
                result = result.Skip((pagenum - 1) * pagesize).Take(pagesize).ToList()
            });
        }

        /// <summary>
        /// 获取分类详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}")]
        public async Task<IActionResult> GetCategory([FromRoute] int id)
        {
            var category = await _context.Select<SpCategory>(id).ToOneAsync<CategoryDto>();
            return ServerResponse.Yes(category);
        }

        /// <summary>
        /// 创建分类
        /// </summary>
        /// <param name="catPid"></param>
        /// <param name="catName"></param>
        /// <param name="catLevel"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task<IActionResult> CreateCategory([FromSmartBody("cat_pid")] int catPid, [FromSmartBody("cat_name")] string catName, [FromSmartBody("cat_level")] int catLevel)
        {
            if (string.IsNullOrWhiteSpace(catName))
                return ServerResponse.BadRequest("必须提供分类名称");

            var source = new SpCategory() { CatPid = catPid, CatName = catName, CatLevel = catLevel };
            source.CatId = (int)await _context.Insert<SpCategory>(source).ExecuteIdentityAsync();

            var category = await _context.Select<SpCategory>(source.CatId).ToOneAsync<CategoryDto>();
            return ServerResponse.Yes(category);
        }


        /// <summary>
        /// 更新分类
        /// </summary>
        /// <param name="id"></param>
        /// <param name="catName"></param>
        /// <returns></returns>
        [HttpPut("{id}")]
        public async Task<IActionResult> UpdateCategory([FromRoute] int id, [FromSmartBody("cat_name")] string catName)
        {
            if (string.IsNullOrWhiteSpace(catName))
                return ServerResponse.BadRequest("必须提供分类名称");

            var categories = await _context.Update<SpCategory>(id).SetDto(new { CatName = catName }).ExecuteAffrowsAsync();
            if (categories > 0)
            {
                var category = await _context.Select<SpCategory>(id).ToOneAsync<CategoryDto>();
                return ServerResponse.Yes(category);
            }

            return ServerResponse.No("分类更新失败");
        }

        /// <summary>
        ///   删除分类
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteCategory([FromRoute] int id)
        {
            await _context.Update<SpCategory>(id).SetDto(new { CatDeleted = 1 }).ExecuteAffrowsAsync();
            return ServerResponse.Yes();
        }


        /// <summary>
        ///   获取分类属性列表
        /// </summary>
        /// <param name="id"></param>
        /// <param name="sel">only:输入框(唯一)  many:后台下拉列表/前台单选框</param>
        /// <returns></returns>
        [HttpGet("{id}/Attributes")]
        public async Task<IActionResult> GetCategoryAttributes([FromRoute] int id, string sel)
        {
            var attributes = await _context.Select<SpAttribute>().Where(a => a.CatId == id && a.AttrSel == sel).ToListAsync();
            return ServerResponse.Yes(attributes);
        }

        /// <summary>
        ///   获取分类属性
        /// </summary>
        /// <param name="id"></param>
        /// <param name="attrId"></param>
        /// <returns></returns>
        [HttpGet("{id}/Attributes/{attrId}")]
        public async Task<IActionResult> GetCategoryAttribute([FromRoute] int id, [FromRoute] int attrId)
        {
            var attribute = await _context.Select<SpAttribute>().Where(a => a.CatId == id && a.AttrId == attrId).ToOneAsync();
            var obj = attribute.Omit("delete_time");
            return ServerResponse.Yes(obj);
        }

        /// <summary>
        ///   创建分类属性
        /// </summary>
        /// <param name="id"></param>
        /// <param name="attrName"></param>
        /// <param name="attrSel"></param>
        /// <param name="attrVals"></param>
        /// <returns></returns>
        [HttpPost("{id}/Attributes")]
        public async Task<IActionResult> CreateCategoryAttribute([FromRoute] int id, [FromSmartBody("attr_name")] string attrName, [FromSmartBody("attr_sel")] string attrSel, [FromSmartBody("attr_vals")] string attrVals)
        {
            if (string.IsNullOrWhiteSpace(attrName))
            {
                return ServerResponse.BadRequest("参数名称不能为空");
            }

            if (string.IsNullOrWhiteSpace(attrSel) || attrSel != "only" && attrSel != "many")
            {
                return ServerResponse.BadRequest("参数 attr_sel 类型必须为 only 或 many");
            }

            var attribute = new SpAttribute() { CatId = id, AttrName = attrName, AttrSel = attrSel, AttrVals = attrVals ?? "", AttrWrite = attrSel == "many" ? "list" : "manual" };
            attribute.AttrId = await _context.Insert<SpAttribute>(attribute).ExecuteAffrowsAsync();
            var obj = attribute.Omit("delete_time");
            return ServerResponse.Yes(obj);
        }

        /// <summary>
        ///   更新分类属性
        /// </summary>
        /// <param name="id"></param>
        /// <param name="attrId"></param>
        /// <param name="attrName"></param>
        /// <param name="attrSel"></param>
        /// <param name="attrVals"></param>
        /// <returns></returns>
        [HttpPut("{id}/Attributes/{attrId}")]
        public async Task<IActionResult> UpdateCategoryAttribute([FromRoute] int id, [FromRoute] int attrId, [FromSmartBody("attr_name")] string attrName, [FromSmartBody("attr_sel")] string attrSel, [FromSmartBody("attr_vals")] string attrVals)
        {
            if (string.IsNullOrWhiteSpace(attrName))
            {
                return ServerResponse.BadRequest("参数名称不能为空");
            }

            if (string.IsNullOrWhiteSpace(attrSel) || attrSel != "only" && attrSel != "many")
            {
                return ServerResponse.BadRequest("参数 attr_sel 类型必须为 only 或 many");
            }

            var attributes = await _context.Update<SpAttribute>(attrId).SetDto(new { CatId = id, AttrName = attrName, AttrSel = attrSel, AttrVals = attrVals ?? "", AttrWrite = attrSel == "many" ? "list" : "manual" }).ExecuteAffrowsAsync();

            if (attributes > 0)
            {
                var attribute = await _context.Select<SpAttribute>(attrId).ToOneAsync();
                var obj = attribute.Omit("delete_time");
                return ServerResponse.Yes(obj);
            }

            return ServerResponse.No("更新失败");
        }

        /// <summary>
        ///   删除分类属性
        /// </summary>
        /// <param name="attrId"></param>
        /// <returns></returns>
        [HttpDelete("{id}/Attributes/{attrId}")]
        public async Task<IActionResult> DeleteCategoryAttribute([FromRoute] int attrId)
        {
            var attributes = await _context.Update<SpAttribute>(attrId).SetDto(new { DeleteTime = DateTime.Now }).ExecuteAffrowsAsync();
            if (attributes > 0)
            {
                var attribute = await _context.Select<SpAttribute>(attrId).ToOneAsync();
                var obj = attribute.Omit("delete_time");
                return ServerResponse.Yes(obj);
            }

            return ServerResponse.No("删除失败");
        }
    }
}
